﻿//+-------------------------------------------------------------------------------------------------------------------------------------------------------
//
//Description: ResourceExtensionParameterHolderViewModel
//Author: Aravind Ramarathinam (aravr@microsoft.com)
//
//Copyright © Microsoft Corporation
//Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
//You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
//INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.
// 
//--------------------------------------------------------------------------------------------------------------------------------------------------------



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using VmroleAuthor.Models;

namespace VmroleAuthor.ViewModels
{
    public class ResourceExtensionParameterHolderViewModel : ViewModelBase, IDataErrorInfo, ICleanupParamsAndPayload
    {
        private readonly ResourceExtensionParameterHolder resourceExtensionParameterHolder;
        private readonly VmRoleResourceDefinitionViewModel vmRoleResourceDefinitionViewModel;
        private ParameterizableProperty resExtParameterValue;
        private ParameterViewModel resExtParamViewModel;

        public static class PropertyNames
        {
            public const string ParameterName = "ParameterName";
            public const string ParameterValue = "ParameterValue";          
        }       

        /// <summary>
        /// Constructor
        /// </summary>
        public ResourceExtensionParameterHolderViewModel(ResourceExtensionParameterHolder resourceExtensionParameterHolder, ParameterViewModel resExtParamViewModel, VmRoleResourceDefinitionViewModel vmRoleResourceDefinitionViewModel, bool autoParameterize)
        {
            this.resourceExtensionParameterHolder = resourceExtensionParameterHolder;
            this.vmRoleResourceDefinitionViewModel = vmRoleResourceDefinitionViewModel;
            this.resExtParamViewModel = resExtParamViewModel;
            if (this.resExtParamViewModel != null)
            {
                this.resExtParamViewModel.ViewDefParamInfo.ResourceExtensionParameterReferenedInResourceDefinition = true;
            }           

            if (autoParameterize)
            {
                this.ParameterValue.PropertyValue = ParametersViewModel.AutoGenerateMoniker;
            }
        }

        public ResourceExtensionParameterHolder ResourceExtensionParameterHolder
        {
            get { return this.resourceExtensionParameterHolder; }            
        }      

        public string ParameterName
        {
            get { return this.resourceExtensionParameterHolder.ParameterName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    this.resourceExtensionParameterHolder.ParameterName = value;                  
                }
                this.OnPropertyChanged(PropertyNames.ParameterName);
                this.OnPropertyChanged(PropertyNames.ParameterValue);
            }
        }

        public ParameterViewModel ResourceExtensionParameterViewModel
        {
            get { return this.resExtParamViewModel; }
            set { this.resExtParamViewModel = value; }
        }

        public List<string> AvailableParameters
        {
            get { return this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel.AvailableParameters; }
        }


        private string GetResExtParamName()
        {
            return this.resExtParamViewModel != null ? this.resExtParamViewModel.Name : string.Empty;
        }

        private string GetResExtParamDescription()
        {
            return this.resExtParamViewModel != null ? this.resExtParamViewModel.Description : string.Empty;
        }

        private string GetResExtName()
        {
            string resExtName =  this.resExtParamViewModel != null ? this.resExtParamViewModel.ParentContainerName : string.Empty;
            resExtName = resExtName.Replace("-", string.Empty);
            resExtName = resExtName.Replace("_", string.Empty);           
            Regex rgx = new Regex("\\s+");
            //TODO: 
            resExtName = rgx.Replace(resExtName, string.Empty);
            return resExtName;
        }

        public string GetConstructedParamNameInResdef()
        {
            return this.resExtParamViewModel != null ? this.GetResExtName() + GetResExtParamName() : "ResExt" + PropertyNames.ParameterValue;
        }


        public ParameterizableProperty ParameterValue
        {
            get
            {
                if (this.resExtParameterValue == null)
                {
                    Func<string> paramValueGetter = () => this.resourceExtensionParameterHolder.ParameterValue;
                    Action<string> paramValueSetter = delegate(string value)
                        {
                            this.resourceExtensionParameterHolder.ParameterValue = value;
                            if (this.vmRoleResourceDefinitionViewModel.ResourceDefinition.ResourceExtensionReferences != null && this.vmRoleResourceDefinitionViewModel.ResourceDefinition.ResourceExtensionReferences.Count > 0)
                            {
                                this.vmRoleResourceDefinitionViewModel.ResourceDefinition.ResourceExtensionReferences[0].SetResourceExtensionParameterValues();
                            }
                        };
                
                    // trick :-)
                    Func<string> autoParamHintGetter = () => { string ret = this.GetConstructedParamNameInResdef(); return ret;};

                    if (this.resExtParamViewModel != null)
                    {
                        switch (this.resExtParamViewModel.Type)
                        {
                            case "Int":                                                               
                                this.resExtParameterValue = new IntParameterizableProperty(
                                   string.Format("Resource Extension {0}. Parameter {1}", this.GetResExtName(), this.GetResExtParamName()),                                
                                   paramValueGetter,
                                   paramValueSetter,
                                   autoParamHintGetter,
                                   ParameterType.Int,
                                   string.Format("Resource Extension {0}. Parameter {1}. {2}", this.GetResExtName(), this.GetResExtParamName(), this.GetResExtParamDescription()),                                    
                                   this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                   true,
                                   this.resExtParamViewModel.ViewDefParamInfo);
                                break;
                            case "Bool":
                            case "Boolean":                                
                                this.resExtParameterValue = new BoolParameterizableProperty(
                                   string.Format("Resource Extension {0}. Parameter {1}", this.GetResExtName(), this.GetResExtParamName()),                                      
                                   paramValueGetter,
                                   paramValueSetter,
                                   autoParamHintGetter,
                                   ParameterType.Boolean,
                                   string.Format("Resource Extension {0}. Parameter {1}. {2}", this.GetResExtName(), this.GetResExtParamName(), this.GetResExtParamDescription()),                                     
                                   this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                   true,
                                   this.resExtParamViewModel.ViewDefParamInfo);
                                break;
                            case "Credential":
                                this.resExtParameterValue = new CredentialParameterizableProperty(
                                   string.Format("Resource Extension {0}. Parameter {1}", this.GetResExtName(), this.GetResExtParamName()),                                                      
                                   paramValueGetter,
                                   paramValueSetter,
                                   autoParamHintGetter,
                                   ParameterType.Credential,
                                   string.Format("Resource Extension {0}. Parameter {1}. {2}", this.GetResExtName(), this.GetResExtParamName(), this.GetResExtParamDescription()),                                         
                                   this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                   true,
                                   this.resExtParamViewModel.ViewDefParamInfo);
                                break;
                            case "SecureString":
                                this.resExtParameterValue = new StringParameterizableProperty(
                                   string.Format("Resource Extension {0}. Parameter {1}", this.GetResExtName(), this.GetResExtParamName()),                                                                                        
                                   paramValueGetter,
                                   paramValueSetter,
                                   autoParamHintGetter,
                                   ParameterType.SecureString,
                                   string.Format("Resource Extension {0}. Parameter {1}. {2}", this.GetResExtName(), this.GetResExtParamName(), this.GetResExtParamDescription()),                                                   
                                   this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                   true,
                                   this.resExtParamViewModel.ViewDefParamInfo);
                                break;
                            //case "String":
                            default:
                                this.resExtParameterValue = new StringParameterizableProperty(
                                     string.Format("Resource Extension {0}. Parameter {1}", this.GetResExtName(), this.GetResExtParamName()),                                                                         
                                    paramValueGetter,
                                    paramValueSetter,
                                    autoParamHintGetter,
                                    ParameterType.String,
                                    string.Format("Resource Extension {0}. Parameter {1}. {2}", this.GetResExtName(), this.GetResExtParamName(), this.GetResExtParamDescription()),                                  
                                    this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                    true,
                                    this.resExtParamViewModel.ViewDefParamInfo);
                                break;
                        }                 
                    }
                    else
                    {
                        ViewDefParamInfo viewDefParamInfo = new ViewDefParamInfo
                            {
                                ViewDefParameterType = ViewDefParameterType.String
                            };
                        this.resExtParameterValue = new StringParameterizableProperty(
                                    "ResourceExtensionParameter-" + PropertyNames.ParameterValue,
                                    paramValueGetter,
                                    paramValueSetter,
                                    autoParamHintGetter,
                                    ParameterType.String,                               
                                    string.Format("Resource Extension {0} parameter", this.resExtParamViewModel != null ? this.resExtParamViewModel.Name : string.Empty),
                                    this.vmRoleResourceDefinitionViewModel.ResourceDefinitionParametersViewModel,
                                    true,
                                    viewDefParamInfo
                                    );
                    }
                    
                }
                return this.resExtParameterValue;
            }
        }

        public void Cleanup()
        {
            this.ParameterValue.Cleanup();
        }

        public string this[string propertyName]
        {
            get
            {
                string error = null;
                switch (propertyName)
                {
                    case PropertyNames.ParameterName:
                        error = ParameterizationHelper.ValidateCannotBeParameterizedBySpecification(this.ParameterName);
                        break;                                                            
                }
                return error;
            }
        }

        public string Error { get { return null; } }        
    }
}
